Avastage TypeScript'i täiustatud tehnikaid, kasutades mall-literaale võimsaks stringitüüpide manipuleerimiseks. Õppige stringipõhiseid tüüpe tõhusalt parssima, teisendama ja valideerima.
TypeScript'i mall-literaalide parsimine: täiustatud stringitüüpide manipuleerimine
TypeScript'i tüübisüsteem pakub võimsaid tööriistu andmete manipuleerimiseks ja valideerimiseks kompileerimise ajal. Nende tööriistade hulgas pakuvad mall-literaalid unikaalset lähenemist stringitüüpide manipuleerimisele. See artikkel süveneb mall-literaalide parsimise täiustatud aspektidesse, näidates, kuidas luua keerukat tüübitaseme loogikat stringipõhiste andmete jaoks.
Mis on mall-literaaltüübid?
Mall-literaaltüübid, mis lisati TypeScript 4.1 versioonis, võimaldavad teil defineerida stringitüüpe, mis põhinevad stringiliteraalidel ja teistel tüüpidel. Nad kasutavad tüübi defineerimiseks tagurpidi ülakomasid (`), sarnaselt JavaScripti mall-literaalidele.
Näiteks:
type Color = "red" | "green" | "blue";
type Shade = "light" | "dark";
type ColorCombination = `${Shade} ${Color}`;
// ColorCombination on nüüd "light red" | "light green" | "light blue" | "dark red" | "dark green" | "dark blue"
See pealtnäha lihtne funktsioon avab laia valiku võimalusi stringide kompileerimisaegseks töötlemiseks.
Mall-literaaltüüpide põhikasutus
Enne täiustatud tehnikatesse sukeldumist vaatame üle mõned põhilised kasutusjuhud.
Stringiliteraalide ühendamine
Saate hõlpsasti kombineerida stringiliteraale ja teisi tüüpe uute stringitüüpide loomiseks:
type Greeting = `Hello, ${string}!`;
// Kasutusnäide
const greet = (name: string): Greeting => `Hello, ${name}!`;
const message: Greeting = greet("World"); // Kehtiv
const invalidMessage: Greeting = "Goodbye, World!"; // Viga: Tüüp '"Goodbye, World!"' ei ole omistatav tüübile '`Hello, ${string}!`'.
Unioonitüüpide kasutamine
Unioonitüübid võimaldavad teil defineerida tüübi kui kombinatsiooni mitmest võimalikust väärtusest. Mall-literaalid saavad kaasata unioonitüüpe, et genereerida keerukamaid stringitüüpide unioone:
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";
type Endpoint = `/api/users` | `/api/products`;
type Route = `${HTTPMethod} ${Endpoint}`;
// Route on nüüd "GET /api/users" | "POST /api/users" | "PUT /api/users" | "DELETE /api/users" | "GET /api/products" | "POST /api/products" | "PUT /api/products" | "DELETE /api/products"
Täiustatud mall-literaalide parsimise tehnikad
Mall-literaaltüüpide tegelik jõud peitub nende võimes olla kombineeritud teiste TypeScript'i täiustatud funktsioonidega, nagu tingimuslikud tüübid ja tüüpide järeldamine, et parsida ja manipuleerida stringitüüpe.
Stringitüübi osade järeldamine
Saate kasutada infer võtmesõna tingimusliku tüübi sees, et eraldada stringitüübi spetsiifilisi osi. See on stringitüüpide parsimise alus.
Vaatleme tüüpi, mis eraldab failinimest faililaiendi:
type GetFileExtension = T extends `${string}.${infer Extension}` ? Extension : never;
// Näited
type Extension1 = GetFileExtension<"myFile.txt">; // "txt"
type Extension2 = GetFileExtension<"anotherFile.image.jpg">; // "image.jpg" (haarates viimase laiendi)
type Extension3 = GetFileExtension<"noExtension">; // never
Selles näites kontrollib tingimuslik tüüp, kas sisendtüüp T vastab mustrile ${string}.${infer Extension}. Kui vastab, järeldab see osa pärast viimast punkti Extension tüübimuutujasse, mis seejärel tagastatakse. Vastasel juhul tagastab see never.
Parsimine mitme järeldamisega
Saate kasutada mitutinfer võtmesõna samas mall-literaalis, et eraldada samaaegselt mitu osa stringitüübist.
type ParseConnectionString =
T extends `${infer Protocol}://${infer Host}:${infer Port}` ?
{ protocol: Protocol, host: Host, port: Port } : never;
// Näide
type Connection = ParseConnectionString<"http://localhost:3000">;
// { protocol: "http", host: "localhost", port: "3000" }
type InvalidConnection = ParseConnectionString<"invalid-connection">; // never
See tüüp parsib ühenduse stringi selle protokolli, hosti ja pordi komponentideks.
Rekursiivsed tüübidefinitsioonid keerukaks parsimiseks
Keerukamate stringistruktuuride jaoks saate kasutada rekursiivseid tüübidefinitsioone. See võimaldab teil korduvalt parsida stringitüübi osi, kuni jõuate soovitud tulemuseni.
Oletame, et soovite jaotada stringi tüübitasemel üksikutest märkidest koosnevaks massiiviks. See on oluliselt keerukam.
type StringToArray =
T extends `${infer Char}${infer Rest}`
? StringToArray
: Acc;
// Näide
type MyArray = StringToArray<"hello">; // ["h", "e", "l", "l", "o"]
Selgitus:
StringToArray: See defineerib geneerilise tüübi nimegaStringToArray, mis võtab sisendiks stringitüübiTja valikulise akumulaatoriAcc, mille vaikeväärtus on tühi stringimassiiv. Akumulaator salvestab märke nende töötlemise käigus.T extends `${infer Char}${infer Rest}`: See on tingimusliku tüübi kontroll. See kontrollib, kas sisendstringiTsaab jaotada esimeseks märgiksCharja ülejäänud stringiksRest. Nende osade püüdmiseks kasutatakseinfervõtmesõna.StringToArray: Kui jaotamine õnnestub, kutsume rekursiivselt väljaStringToArrayülejäänud stringigaRestja uue akumulaatoriga. Uus akumulaator luuakse olemasolevaAcclaialilaotamise ja praeguse märgiCharlõppu lisamisega. See lisab tegelikult märgi kogunevasse massiivi.Acc: Kui string on tühi (tingimuslik tüüp ebaõnnestub, mis tähendab, et rohkem märke pole), tagastame kogunenud massiiviAcc.
See näide demonstreerib rekursiooni jõudu stringitüüpide manipuleerimisel. Iga rekursiivne väljakutse eemaldab ühe märgi ja lisab selle massiivi, kuni string on tühi.
Eraldajatega töötamine
Mall-literaale saab hõlpsasti kasutada koos eraldajatega stringide parsimiseks. Oletame, et soovite eraldada komadega eraldatud sõnad.
type SplitString =
T extends `${infer First}${D}${infer Rest}`
? [First, ...SplitString]
: [T];
// Näide
type Words = SplitString<"apple,banana,cherry", ",">; // ["apple", "banana", "cherry"]
See tüüp parsib rekursiivselt stringi igal eraldaja D esinemisel.
Praktilised rakendused
Nendel täiustatud mall-literaalide parsimise tehnikatel on TypeScript'i projektides arvukalt praktilisi rakendusi.
Andmete valideerimine
Saate valideerida stringipõhiseid andmeid konkreetsete mustrite vastu kompileerimise ajal. Näiteks e-posti aadresside, telefoninumbrite või krediitkaardinumbrite valideerimine. See lähenemine annab varajast tagasisidet ja vähendab käitusaegseid vigu.
Siin on näide lihtsustatud e-posti aadressi vormingu valideerimisest:
type EmailFormat = `${string}@${string}.${string}`;
const validateEmail = (email: string): email is EmailFormat => {
// Tegelikkuses kasutataks korrektseks e-posti valideerimiseks palju keerukamat regulaaravaldist.
// See on ainult demonstratsiooni eesmärgil.
return /.+@.+\..+/.test(email);
}
const validEmail: EmailFormat = "user@example.com"; // Kehtiv
const invalidEmail: EmailFormat = "invalid-email"; // Tüüp 'string' ei ole omistatav tüübile '`${string}@${string}.${string}`'.
if(validateEmail(validEmail)) {
console.log("Kehtiv e-post");
}
if(validateEmail("invalid-email")) {
console.log("Seda ei prindita.");
}
Kuigi käitusaegne valideerimine regulaaravaldisega on endiselt vajalik juhtudel, kus tüübikontrollija ei suuda piirangut täielikult jõustada (nt välise sisendi käsitlemisel), pakub EmailFormat tüüp väärtuslikku esimest kaitseliini kompileerimise ajal.
API lõpp-punktide genereerimine
Mall-literaale saab kasutada API lõpp-punkti tüüpide genereerimiseks baas-URL-i ja parameetrite kogumi alusel. See aitab tagada järjepidevuse ja tüübiohutuse API-dega töötamisel.
type BaseURL = "https://api.example.com";
type Resource = "users" | "products";
type ID = string | number;
type GetEndpoint = `${BaseURL}/${T}/${U}`;
// Näited
type UserEndpoint = GetEndpoint<"users", 123>; // "https://api.example.com/users/123"
type ProductEndpoint = GetEndpoint<"products", "abc-456">; // "https://api.example.com/products/abc-456"
Koodi genereerimine
Keerukamates stsenaariumides saab mall-literaaltüüpe kasutada koodi genereerimise protsesside osana. Näiteks SQL-päringute genereerimine skeemi alusel või kasutajaliidese komponentide loomine konfiguratsioonifaili põhjal.
Rahvusvahelistamine (i18n)
Mall-literaalid võivad olla väärtuslikud i18n stsenaariumides. Näiteks kaaluge süsteemi, kus tõlkevõtmed järgivad kindlat nimekonventsiooni:
type SupportedLanguages = 'en' | 'es' | 'fr';
type TranslationKeyPrefix = 'common' | 'product' | 'checkout';
type TranslationKey = `${TPrefix}.${string}`;
// Kasutusnäide:
const getTranslation = (key: TranslationKey, lang: SupportedLanguages): string => {
// Simuleerime tõlke hankimist ressursikogumist võtme ja keele alusel
const translations: Record> = {
'common.greeting': {
en: 'Hello',
es: 'Hola',
fr: 'Bonjour',
},
'product.description': {
en: 'A fantastic product!',
es: '¡Un producto fantástico!',
fr: 'Un produit fantastique !',
},
};
const translation = translations[key]?.[lang];
return translation || `Tõlget ei leitud võtmele: ${key} keeles: ${lang}`;
};
const englishGreeting = getTranslation('common.greeting', 'en'); // Hello
const spanishDescription = getTranslation('product.description', 'es'); // ¡Un producto fantástico!
const unknownTranslation = getTranslation('nonexistent.key' as TranslationKey, 'en'); // Tõlget ei leitud võtmele: nonexistent.key keeles: en
Tüüp TranslationKey tagab, et kõik tõlkevõtmed järgivad ühtset vormingut, mis lihtsustab tõlgete haldamise protsessi ja vigade ennetamist.
Piirangud
Kuigi mall-literaaltüübid on võimsad, on neil ka piiranguid:
- Keerukus: Keerukas parsimisloogika võib kiiresti muutuda raskesti loetavaks ja hooldatavaks.
- Jõudlus: Mall-literaaltüüpide laialdane kasutamine võib mõjutada kompileerimisaegset jõudlust, eriti suurtes projektides.
- Tüübiohutuse lüngad: Nagu e-posti valideerimise näites demonstreeriti, ei ole kompileerimisaegsed kontrollid mõnikord piisavad. Käitusaegne valideerimine on endiselt vajalik juhtudel, kus välised andmed peavad vastama rangetele vormingutele.
Parimad praktikad
Mall-literaaltüüpide tõhusaks kasutamiseks järgige neid parimaid praktikaid:
- Hoidke see lihtsana: Jaotage keerukas parsimisloogika väiksemateks, hallatavateks tüüpideks.
- Dokumenteerige oma tüübid: Dokumenteerige selgelt oma mall-literaaltüüpide eesmärk ja kasutusviis.
- Testige oma tüüpe: Looge ühiktestid, et tagada oma tüüpide ootuspärane käitumine.
- Tasakaalustage kompileerimis- ja käitusaegset valideerimist: Kasutage mall-literaaltüüpe põhiliseks valideerimiseks ja käitusaegseid kontrolle keerukamate stsenaariumide jaoks.
Kokkuvõte
TypeScript'i mall-literaaltüübid pakuvad võimsat ja paindlikku viisi stringitüüpide manipuleerimiseks kompileerimise ajal. Kombineerides mall-literaale tingimuslike tüüpide ja tüüpide järeldamisega, saate luua keerukat tüübitaseme loogikat stringipõhiste andmete parsimiseks, valideerimiseks ja teisendamiseks. Kuigi on piiranguid, mida arvesse võtta, võivad mall-literaaltüüpide kasutamise eelised tüübiohutuse ja koodi hooldatavuse osas olla märkimisväärsed.
Nende täiustatud tehnikate valdamisega saavad arendajad luua robustsemaid ja usaldusväärsemaid TypeScript'i rakendusi.
Edasine uurimine
Oma arusaamise süvendamiseks mall-literaaltüüpidest kaaluge järgmiste teemade uurimist:
- Vastendatud tüübid (Mapped Types): Õppige, kuidas teisendada objektitüüpe mall-literaaltüüpide põhjal.
- Abistavad tüübid (Utility Types): Uurige sisseehitatud TypeScript'i abistavaid tüüpe, mida saab kasutada koos mall-literaaltüüpidega.
- Täiustatud tingimuslikud tüübid: Süvenege tingimuslike tüüpide võimetesse keerukama tüübitaseme loogika jaoks.